package com.iss.umservice.common;

import java.util.ArrayList;
import java.util.List;

import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.iss.umservice.common.xml.XmlDomNode;
import com.iss.umservice.common.xml.XmlDomParser;


/**
 * <p>
 * [功能简述] 读取系统配置文件classpath下的gzt.xml
 * <p>
 * <p>
 * [详细描述] 读取系统配置文件classpath下的gzt.xml
 * </p>
 * @author  gcxu
 * @version  [GZT 1.00, Aug 12, 2010]
 * @see  [相关类/方法]
 * @since  [GZT]
 */
public class XmlConfig
{
    /** xml 文档对象 */
    private static XmlDomNode document;
    
    /** 工具类单例对象 */
    private static XmlConfig instance;
    
    /** xml在系统中的路径 */
    private static String xmlFilePath = "/config.xml";
    
    /** gzt.xml 根节点前缀 */
    private static final String MODULES_PREFIX = "//modules/";
    
    /** xPath求文本内容常量 */
    private static final String XPATH_TEXT = "/text()";
    
    /** 点号 */
    public static final String DOT = ".";
    
    /** 点号分隔符正则 */
    public static final String DOT_REX = "\\.";
    
    /**
     * 默认构造函数
     */
    private XmlConfig()
    {
        // 读取配置文件
        document = XmlDomParser.parser(xmlFilePath);
    }
    
    /**  
     * 获得工具类实例  
     * @return  
     */
    public static XmlConfig newInstance()
    {
        if (instance == null)
        {
            synchronized (XmlConfig.class)
            {
                if (instance == null)
                {
                    instance = new XmlConfig();
                }
            }
        }
        
        return instance;
    }
    
    /**
     * 
     * <p>
     * [功能简述] xml文件路径
     * <p>
     * <p>
     * [详细描述] xml文件路径
     * </p>
     * @return String
     * @exception throws [违例类型] [违例说明]
     * @see [类、类#方法、类#成员]
     */
    public String getXmlFilePath()
    {
        return xmlFilePath;
    }
    
    /**
     * 
     * <p>
     * [功能简述]查询指定节点的文本内容
     * <p>
     * <p>
     * [详细描述]查询指定节点的文本内容,用.号标识层次关系
     * </p>
     * @param nodeName 节点名称(支持格式parent.node)
     * @return String
     * @exception throws [违例类型] [违例说明]
     * @see [类、类#方法、类#成员]
     */
    public String getModuleNodeValue(String nodeName)
    {
        if (null == nodeName || "".equals(nodeName))
        {
            return "";
        }
        
        if (nodeName.indexOf(DOT) != -1)
        {
            nodeName = nodeName.replaceAll(DOT_REX, "/");
        }
        StringBuffer sb = new StringBuffer();
        sb.append(MODULES_PREFIX);
        sb.append(nodeName);
        sb.append(XPATH_TEXT);
        return document.getNodeText(sb.toString());
    }
    
    public List<String> getListValue(String nodeName)
    {
        List<String> re = new ArrayList(); 
        String[] values = XmlConfig.newInstance()
                .getModuleNodeValue(nodeName)
                .split(",");
        for (int i = 0; i < values.length; i++)
        {
            re.add(values[i]);
        }
        return re;
    }
    
    /**  
     *  依据当前元素名称，查找该元素的制定属性  
     * @param nodeName  节点名称(支持 parent.node.attribute)
     * @return  String 属性值
     */
    public String getModuleNodeAttribute(String nodeName)
    {
        if (null == nodeName || "".equals(nodeName))
        {
            return "";
        }
        
        String attrName = "";
        String nodeN = "";
        if (nodeName.indexOf(DOT) != -1)
        {
            int offset = nodeName.lastIndexOf(DOT);
            nodeN = nodeName.substring(0, offset);
            attrName = nodeName.substring(offset + 1, nodeName.length());
            if (nodeN.indexOf(DOT) != -1)
            {
                nodeN = nodeN.replaceAll(DOT_REX, "/");
            }
        }
        else
        {
            return "";
        }
        
        StringBuffer sb = new StringBuffer();
        sb.append(MODULES_PREFIX);
        sb.append(nodeN);
        sb.append("[@");
        sb.append(attrName);
        sb.append("]");
        
        Node node = document.getNode(sb.toString());
        if (null == node)
        {
            return "";
        }
        String attrVal = "";
        NamedNodeMap attrs = node.getAttributes();
        int len = attrs.getLength();
        for (int j = 0; j < len; j++)
        {
            Node attr = attrs.item(j);
            if (attr.getNodeName().equals(attrName))
            {
                attrVal = attr.getNodeValue();
                break;
            }
        }
        
        return attrVal;
    }
    
    /**  
     *  依据当前元素名称，查找该元素的指定子节点集合  
     * @param nodeName  节点名称(支持 parent.node.attribute)
     * @return  NodeList 子节点集合
     */
    public NodeList getModuleNodeList(String nodeName)
    {
        if (null == nodeName || "".equals(nodeName))
        {
            return null;
        }
        
        if (nodeName.indexOf(DOT) != -1)
        {
            nodeName = nodeName.replaceAll(DOT_REX, "/");
        }
        StringBuffer sb = new StringBuffer();
        sb.append(MODULES_PREFIX);
        sb.append(nodeName);
        NodeList nodeList = document.getNodeList(sb.toString());
        if (null == nodeList || nodeList.getLength() == 0)
        {
            return null;
        }
        
        // 返回指定节点的子节点
        return nodeList.item(0).getChildNodes();
    }
}